<template>
  <div class="comment-list">
    <!-- 统计卡片 -->
    <el-row :gutter="20" class="statistics-cards">
      <el-col :span="12">
        <el-card shadow="hover">
          <div class="statistics-item">
            <div class="statistics-title">今日评论</div>
            <div class="statistics-value">{{ todayComments }}</div>
            <div class="statistics-trend" :class="{ 'up': commentsTrend > 0, 'down': commentsTrend < 0 }">
              {{ commentsTrend > 0 ? '+' : '' }}{{ commentsTrend }}%
            </div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="12">
        <el-card shadow="hover">
          <div class="statistics-item">
            <div class="statistics-title">总评论数</div>
            <div class="statistics-value">{{ totalComments }}</div>
            <div class="statistics-trend" :class="{ 'up': totalTrend > 0, 'down': totalTrend < 0 }">
              {{ totalTrend > 0 ? '+' : '' }}{{ totalTrend }}%
            </div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 搜索栏 -->
    <el-card class="search-card">
      <el-form :inline="true" :model="searchForm" class="search-form">
        <el-form-item>
          <el-input
            v-model="searchForm.keyword"
            placeholder="搜索评论内容"
            clearable
            @clear="handleSearch"
            @keyup.enter.native="handleSearch"
          >
            <el-button slot="append" icon="el-icon-search" @click="handleSearch" plain></el-button>
          </el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleAdd" plain>添加评论</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <!-- 评论列表 -->
    <el-card class="table-card">
      <el-table
        v-loading="loading"
        :data="filteredComments"
        border
        style="width: 100%"
        row-key="commentId"
      >
        <el-table-column prop="commentId" label="评论ID" width="220"></el-table-column>
        <el-table-column label="用户" width="120">
          <template slot-scope="scope">
            <span>{{ getUserNickname(scope.row.userId, scope.row) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="商品" width="150">
          <template slot-scope="scope">
            <span>{{ getProductTitle(scope.row.productId, scope.row) }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="content" label="评论内容" min-width="200" show-overflow-tooltip></el-table-column>
        <el-table-column prop="createTime" label="评论时间" width="180">
          <template slot-scope="scope">
            {{ formatDate(scope.row.createTime) }}
          </template>
        </el-table-column>
        <el-table-column label="操作" width="150" fixed="right">
          <template slot-scope="scope">
            <el-button
              size="mini"
              type="primary"
              @click="handleEdit(scope.row)"
              plain
            >编辑</el-button>
            <el-button
              size="mini"
              type="danger"
              @click="handleDelete(scope.row)"
              plain
            >删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <div class="pagination-container">
        <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="currentPage"
          :page-sizes="[10, 20, 50, 100]"
          :page-size="pageSize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
        ></el-pagination>
      </div>
    </el-card>

    <!-- 添加/编辑评论对话框 -->
    <el-dialog
      :title="dialogTitle"
      :visible.sync="dialogVisible"
      width="500px"
      @close="handleDialogClose"
    >
      <el-form
        ref="commentForm"
        :model="commentForm"
        :rules="rules"
        label-width="80px"
      >
        <el-form-item label="用户" prop="userId">
          <el-select v-model="commentForm.userId" placeholder="选择用户" filterable>
            <el-option
              v-for="user in users"
              :key="user.userId"
              :label="user.nickname"
              :value="user.userId"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="商品" prop="productId">
          <el-select v-model="commentForm.productId" placeholder="选择商品" filterable>
            <el-option
              v-for="product in products"
              :key="product.productId"
              :label="product.title"
              :value="product.productId"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="评论内容" prop="content">
          <el-input
            type="textarea"
            v-model="commentForm.content"
            :rows="4"
            placeholder="请输入评论内容"
          ></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false" plain>取 消</el-button>
        <el-button type="primary" @click="handleSubmit" :loading="submitting" plain>确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import commentService from '@/services/comment.service'
import userService from '@/services/user.service'
import productService from '@/services/product.service'
import { formatDate } from '@/utils/date'

export default {
  name: 'CommentList',
  data() {
    return {
      // 统计数据
      todayComments: 0,
      commentsTrend: 0,
      totalComments: 0,
      totalTrend: 0,
      
      // 搜索表单
      searchForm: {
        keyword: ''
      },
      
      // 表格数据
      comments: [],
      loading: false,
      currentPage: 1,
      pageSize: 10,
      total: 0,
      
      // 对话框
      dialogVisible: false,
      dialogTitle: '',
      submitting: false,
      commentForm: {
        commentId: null,
        userId: null,
        productId: null,
        content: ''
      },
      rules: {
        userId: [
          { required: true, message: '请选择用户', trigger: 'change' }
        ],
        productId: [
          { required: true, message: '请选择商品', trigger: 'change' }
        ],
        content: [
          { required: true, message: '请输入评论内容', trigger: 'blur' },
          { min: 1, max: 200, message: '长度在 1 到 200 个字符', trigger: 'blur' }
        ]
      },
      
      // 选项数据
      users: [],
      products: []
    }
  },
  
  computed: {
    filteredComments() {
      if (!this.searchForm.keyword) {
        return this.comments;
      }
      const keyword = this.searchForm.keyword.toLowerCase();
      return this.comments.filter(item =>
        (item.content && item.content.toLowerCase().includes(keyword))
      );
    }
  },
  
  created() {
    this.fetchData()
    this.fetchUsers()
    this.fetchProducts()
  },
  
  methods: {
    formatDate,
    
    // 获取数据
    async fetchData() {
      try {
        this.loading = true
        const [listRes, statsRes] = await Promise.all([
          commentService.getList({
            page: this.currentPage,
            pageSize: this.pageSize,
            keyword: this.searchForm.keyword
          }),
          commentService.getStatistics()
        ])
        
        // 处理评论列表数据
        if (listRes && listRes.code === 200) {
          let data = listRes.data
          let commentList = []; // 临时变量，用于存储确定的评论数组
          let totalCount = 0;   // 临时变量，用于存储确定的总数

          if (data && typeof data === 'object') {
            // 首先，尝试从data.total或data.totalCount获取总数
            if (data.total !== undefined) {
                totalCount = data.total;
            } else if (data.totalCount !== undefined) {
                totalCount = data.totalCount;
            }

            // 然后，确定实际的评论数组
            if (data.items && Array.isArray(data.items)) {
              commentList = data.items;
              // 如果没有明确提供总数，但有items数组，则使用其长度
              if (totalCount === 0) {
                  totalCount = commentList.length;
              }
            } else if (data.$values && Array.isArray(data.$values)) {
              // 处理JSON.NET格式的数据
              commentList = this.processJsonNetData(data.$values);
              // 如果没有明确提供总数，但有$values数组，则使用其长度
              if (totalCount === 0) {
                  totalCount = commentList.length;
              }
            } else if (Array.isArray(data)) { // 处理data本身就是数组的情况
              commentList = this.processJsonNetData(data);
              // 如果没有明确提供总数且data是直接数组，则使用其长度
              if (totalCount === 0) {
                  totalCount = commentList.length;
              }
            } else {
              commentList = [];
            }
          } else if (Array.isArray(data)) { // 处理listRes.data直接是数组的情况
            commentList = this.processJsonNetData(data);
            totalCount = data.length;
          } else {
            commentList = [];
          }

          // 过滤掉任何 null 或 undefined 的评论对象
          this.comments = commentList.filter(item => item !== null && item !== undefined);
          this.total = totalCount;

        } else {
          this.comments = []
          this.total = 0
        }
        
        // 处理统计数据
        if (statsRes && statsRes.code === 200) {
          const stats = statsRes.data
          this.todayComments = stats.todayComments || 0
          this.commentsTrend = stats.commentsTrend || 0
          this.totalComments = stats.totalComments || 0
          this.totalTrend = stats.totalTrend || 0
        } else {
          // 设置默认统计数据
          this.todayComments = 0
          this.commentsTrend = 0
          this.totalComments = 0
          this.totalTrend = 0
        }
      } catch (error) {
        console.error('获取数据失败:', error)
        this.$message.error('获取数据失败')
        // 设置默认值
        this.comments = []
        this.total = 0
        this.todayComments = 0
        this.commentsTrend = 0
        this.totalComments = 0
        this.totalTrend = 0
      } finally {
        console.log('Final comments (JSON):', JSON.stringify(this.comments, null, 2));
        console.log('Final total:', this.total);
        this.loading = false
      }
    },
    
    // 处理JSON.NET格式的数据，解析$ref引用
    processJsonNetData(data) {
      if (!Array.isArray(data)) {
        console.log('processJsonNetData: 输入不是数组', data);
        return [];
      }

      console.log('processJsonNetData: 开始处理数据', data.length, '项');

      const idMap = new Map();

      // 递归函数：第一阶段，收集所有 $id 对象
      const collectIdsRecursive = (currentObj) => {
        if (currentObj === null || typeof currentObj !== 'object') {
          return;
        }

        if (currentObj.$id) {
          idMap.set(currentObj.$id, currentObj);
        }

        if (Array.isArray(currentObj)) {
          // 如果是数组，遍历其元素
          currentObj.forEach(item => collectIdsRecursive(item));
        } else {
          // 如果是对象，遍历其属性
          for (const key in currentObj) {
            // 确保是对象自身的属性，而不是原型链上的
            if (Object.prototype.hasOwnProperty.call(currentObj, key)) {
              // 如果是 $values 数组，递归遍历其元素
              if (key === '$values' && Array.isArray(currentObj[key])) {
                  currentObj[key].forEach(item => collectIdsRecursive(item));
              } 
              // 如果是普通对象属性，并且不是 $ref 或 $id（$id已处理），则递归遍历
              else if (typeof currentObj[key] === 'object' && currentObj[key] !== null && key !== '$ref' && key !== '$id') {
                  collectIdsRecursive(currentObj[key]);
              }
            }
          }
        }
      };

      // 第一阶段：从根数据（评论数组）开始递归收集所有 $id
      collectIdsRecursive(data);
      
      console.log('processJsonNetData: 收集到', idMap.size, '个有$id的对象');

      // 递归函数：第二阶段，解析 $ref 引用并清理数据
      const resolveRefsRecursive = (currentObj) => {
        if (currentObj === null || typeof currentObj !== 'object') {
          return currentObj;
        }

        // 如果是 $ref 引用，从 idMap 中获取实际对象
        if (currentObj.$ref) {
          return idMap.get(currentObj.$ref);
        }

        // 如果是数组，映射其元素
        if (Array.isArray(currentObj)) {
          return currentObj.map(item => resolveRefsRecursive(item));
        }

        // 如果是对象，创建一个新对象并处理其属性
        const newObj = {};
        for (const key in currentObj) {
          // 确保是对象自身的属性
          if (Object.prototype.hasOwnProperty.call(currentObj, key)) {
            // 跳过 JSON.NET 的元数据 $id 和 $values
            if (key === '$id' || key === '$values') {
              continue;
            }
            if (typeof currentObj[key] === 'object' && currentObj[key] !== null) {
              newObj[key] = resolveRefsRecursive(currentObj[key]);
            } else {
              newObj[key] = currentObj[key];
            }
          }
        }
        return newObj;
      };

      // 第二阶段：递归解析引用并清理数据
      const processedData = resolveRefsRecursive(data);

      console.log('processJsonNetData: 处理完成，返回', processedData.length, '项');
      return processedData;
    },
    
    // 获取用户列表
    async fetchUsers() {
      try {
        const res = await userService.getUsers()
        if (res && res.code === 200) {
          let data = res.data
          if (data && typeof data === 'object') {
            if (data.$values && Array.isArray(data.$values)) {
              this.users = this.processJsonNetData(data.$values)
            } else if (Array.isArray(data)) {
              this.users = this.processJsonNetData(data)
            } else {
              this.users = []
            }
          } else {
            this.users = []
          }
        } else {
          this.users = []
        }
      } catch (error) {
        console.error('获取用户列表失败:', error)
        this.users = []
      }
    },
    
    // 获取商品列表
    async fetchProducts() {
      try {
        const res = await productService.getProducts()
        if (res && res.code === 200) {
          let data = res.data
          if (data && typeof data === 'object') {
            if (data.$values && Array.isArray(data.$values)) {
              this.products = this.processJsonNetData(data.$values)
            } else if (Array.isArray(data)) {
              this.products = this.processJsonNetData(data)
            } else {
              this.products = []
            }
          } else {
            this.products = []
          }
        } else {
          this.products = []
        }
      } catch (error) {
        console.error('获取商品列表失败:', error)
        this.products = []
      }
    },
    
    // 搜索
    handleSearch() {
      this.currentPage = 1
      this.fetchData()
    },
    
    // 分页
    handleSizeChange(val) {
      this.pageSize = val
      this.fetchData()
    },
    
    handleCurrentChange(val) {
      this.currentPage = val
      this.fetchData()
    },
    
    // 添加评论
    handleAdd() {
      this.dialogTitle = '添加评论'
      this.commentForm = {
        commentId: null,
        userId: null,
        productId: null,
        content: ''
      }
      this.dialogVisible = true
    },
    
    // 编辑评论
    handleEdit(row) {
      this.dialogTitle = '编辑评论'
      this.commentForm = { ...row }
      this.dialogVisible = true
    },
    
    // 删除评论
    handleDelete(row) {
      // 检查 commentId 是否存在，避免发送 /undefined 请求
      if (!row.commentId) {
        this.$message.error('评论ID缺失，无法执行删除操作。')
        console.error('尝试删除的评论缺少commentId:', row)
        return // 阻止继续执行删除操作
      }

      this.$confirm('确认删除该评论吗？', '提示', {
        type: 'warning'
      }).then(async () => {
        try {
          // 确保 commentId 是字符串类型，以防后端API对GUID类型有严格要求
          await commentService.delete(String(row.commentId))
          this.$message.success('删除成功')
          this.fetchData()
        } catch (error) {
          console.error('删除失败:', error)
          this.$message.error('删除失败')
        }
      }).catch(() => {})
    },
    
    // 提交表单
    handleSubmit() {
      // 在验证前打印 commentForm 的内容，以便调试
      console.log('提交前 commentForm:', JSON.parse(JSON.stringify(this.commentForm)))

      this.$refs.commentForm.validate(async valid => {
        console.log('前端表单验证结果 (valid):', valid) // 打印验证结果
        if (!valid) {
          this.$message.warning('请检查表单填写是否完整。') // 提示用户
          return
        }
        
        try {
          this.submitting = true
          if (this.commentForm.commentId) {
            await commentService.update(this.commentForm.commentId, this.commentForm)
            this.$message.success('更新成功')
          } else {
            await commentService.create(this.commentForm)
            this.$message.success('添加成功')
          }
          this.dialogVisible = false
          this.fetchData()
        } catch (error) {
          console.error('提交失败:', error)
          this.$message.error('提交失败')
        } finally {
          this.submitting = false
        }
      })
    },
    
    // 关闭对话框
    handleDialogClose() {
      this.$refs.commentForm.resetFields()
    },
    
    // 获取用户昵称
    getUserNickname(userId, comment) {
      if (!userId) return '-'
      
      // 优先从评论对象中获取用户信息（如果JSON.NET解析后包含完整用户数据）
      if (comment && comment.user && comment.user.nickname) {
        return comment.user.nickname
      }
      
      // 否则从users数组中查找
      const user = this.users.find(u => u.userId === userId)
      return user ? user.nickname : '未知用户'
    },
    
    // 获取商品标题
    getProductTitle(productId, comment) {
      if (!productId) return '-'
      
      // 优先从评论对象中获取商品信息（如果JSON.NET解析后包含完整商品数据）
      if (comment && comment.product && comment.product.title) {
        return comment.product.title
      }
      
      // 否则从products数组中查找
      const product = this.products.find(p => p.productId === productId)
      return product ? product.title : '未知商品'
    }
  }
}
</script>

<style lang="scss" scoped>
.comment-list {
  padding: 20px;
  
  .statistics-cards {
    margin-bottom: 20px;
    
    .statistics-item {
      text-align: center;
      
      .statistics-title {
        font-size: 14px;
        color: #909399;
        margin-bottom: 10px;
      }
      
      .statistics-value {
        font-size: 24px;
        font-weight: bold;
        color: #303133;
        margin-bottom: 10px;
      }
      
      .statistics-trend {
        font-size: 12px;
        
        &.up {
          color: #67c23a;
        }
        
        &.down {
          color: #f56c6c;
        }
      }
    }
  }
  
  .search-card {
    margin-bottom: 20px;
    
    .search-form {
      display: flex;
      justify-content: space-between;
      align-items: center;
    }
  }
  
  .table-card {
    .pagination-container {
      margin-top: 20px;
      text-align: right;
    }
  }
}
</style> 